﻿using System;
using System.Collections.Generic;
using System.Linq;

using System.IO;
using System.Runtime.Serialization.Formatters.Binary;    // Namespace til serialisering
using System.Collections;     // skal bruges til IEnumerator

using System.Text;

using Model;    // Bruger namespace for Model-komponenten
using Interfaces;    // Bruger namespace for Interface-komponenten

using System.Data; // DEN HER ER NY vi bruger dne til Data tabels 
namespace Controller
{
    // Ideen er, at FrisørSystem-klassen skal være en Controllerklasse, der skal have styr på 
    // både ordrer og varer.
    //
    // Det er også Frisørsystem der skal sørge for at gemme/hente alle data fra/til både ordre og varer
    
    public class FrisørSystem
    {
        private DBFacade minDBFacade;          // Associering til database-facade-klasse

        private OrdreCollection ordreCol;   // aggregering af ordrecollection
        private VareCollection vareCol;     // aggregering af varecollection

        private Ordre aktuelOrdre;   // session-variabel for aktuel ordre       

        private Vare aktuelVare;   // session-variabel for aktuel vare       


        private List<DataTable> SamletData;
        
        // Konstruktør
        public FrisørSystem()
        {
            ordreCol = new OrdreCollection();
            vareCol = new VareCollection();
            aktuelOrdre = null;
            aktuelVare = null;

            minDBFacade = new DBFacade(this);
            SamletData = minDBFacade.IndlæsFraDatabasen(); // Indlæse fra databasen // NYTTT HER

            DataTable Tvarer = SamletData[0];
            foreach (DataRow linje in Tvarer.Rows)
            {
                vareCol.TilfoejVare(Convert.ToInt64(linje[0]), Convert.ToString(linje[1]), Convert.ToDouble(linje[2])); 
            }

        }

        #region   ******* Operationer på varer ***********

        public List<long> FindVarenumre()
        {
            return vareCol.GetVarenumre();
        }

        // Pre: 
        // Post: Vare er oprettet i databasen
        // Out: Ivaredata returneret, hvis vareoprettelse lykkedes, ellers null 
        public IVaredata TilfoejVare(string betegnelse, double pris)
        {
            long varenr = minDBFacade.OpretVare(betegnelse, pris);

            if (varenr > -1) // -1 returneres hvis der ikke blev oprettet en vare
            {
                aktuelVare = vareCol.TilfoejVare(varenr, betegnelse, pris);
                return (IVaredata)aktuelVare;
            }
            else return null;
        }


        // ændring pga sessioncontroller *** Ulla
        // Pre: varenr findes i systemet
        // Post: IVvaredata returneret.
        public IVaredata FindVare(long varenr)
        {
            aktuelVare = vareCol.FindVare(varenr);
            return (IVaredata) aktuelVare; // jeg behøver egentlig ikke caste, vare implementerer Varedata *** Ulla
        }

        

        // Pre: varen med varenr findes i systemet
        // Post: True returneret, hvis beholdningen opskrevet med antal (nyBeholdning out), ellers false (systemfejl)
        public bool ModtagVarer(uint antal, out uint nyBeholdning)
        {


            if (minDBFacade.JusterVarebeholdning(aktuelVare.Varenr, antal))
            {
                nyBeholdning = aktuelVare.ModtagVarer(antal);
                return true;
            }
            else
            {
                nyBeholdning = 0;
                return false;
            }
        }




        // Pre: varen med varenr er læst tidligere
        // Post: True returneret, hvis varejustering lykkedes, ellers false (systemfejl)
        public bool JusterVare(string betegnelse, double pris)
        {
            if (minDBFacade.RetVare(aktuelVare.Varenr, betegnelse, pris))
            {
                aktuelVare.Betegnelse = betegnelse;
                aktuelVare.Pris = pris;
                return true;
            }
            else return false;
           // GemData();
        }



        public void FjernVare()
        {
            if (minDBFacade.SletVare(aktuelVare.Varenr))
            {
                vareCol.FjernVare(aktuelVare);
            }
        }

        public double VisLagerbinding()
        {
            return vareCol.VisLagerbinding();
        }

        public VareCollection GetVareCollection()
        {
            return vareCol;
        }

        public IEnumerator GetVareEnumerator()
        {
            return vareCol.GetVareIterator();
        }
        #endregion

        #region    ******** Operationer på ordrer ***********

        // ændring pga sessioncontroller *** Ulla
        public void RegistrerOrdre(int ordrenr, DateTime ordredato, DateTime leveringsdato)
        {
            aktuelOrdre = ordreCol.OpretOrdre(ordrenr, ordredato, leveringsdato); // når jeg opretter en ordre skal sessionControlleren vide det *** Ulla
            //GemData();
        }

       
        public void RegistrerOrdrelinie(IVaredata vare, int antal)
        {
            // før ledte jeg efter ordren her, men den ligger i aktuelOrdre
            Vare minVare = vareCol.FindVare(vare.Varenr); // jeg finder varen ud fra varenr

            aktuelOrdre.Opretordrelinie(minVare, antal);
            //GemData();
        }


        // ændret i forbindelse med brug af sessioncontroller *** Ulla
        // sessionvariablen skal pege på den fundne ordre
        public IOrdredata FindOrdre(int ordrenr)
        {
            aktuelOrdre = ordreCol.FindOrdre(ordrenr);
            return aktuelOrdre;
        }

        public List<int> FindOrdrenumreEksp()
        {
            return ordreCol.FindOrdrenumreEksp();
        }

        // ændret i forbindelse med brug af sessioncontroller
        // vi behøver ikke ordrenr som parameter, vi ved hvilken ordre det handler om *** Ulla
        public bool KanEkspederes()
        {
            return aktuelOrdre.KanEkspederes();
        }

        // ændret i forbindelse med brug af sessionController
        public void EkspederOrdre()
        {
            aktuelOrdre.EkspederOrdre(); // da jeg kender den aktuelle ordre, kan jeg arbejde direkte på den *** Ulla
           // GemData();
        }

        public IEnumerator GetOrdrelinieEnumerator()
        {
            return aktuelOrdre.GetOrdrelinieIterator();
        }

        #endregion

        #region ************ Persistens fil (udkommenteret) *****************

        //// ordresystem serialiseres til fil
        //private void GemData()
        //{
        //    // Skab fil for skrivning
        //    FileStream fileStream = new FileStream(FILNAVN, FileMode.Create, FileAccess.Write);

        //    // skab binary-formatter til objekt-serialisering
        //    BinaryFormatter binFormatter = new BinaryFormatter();

        //    // Serialisér ordresystem til filestream
        //    binFormatter.Serialize(fileStream, this);

        //    fileStream.Close();
        //}

        ///********** Indlæsning af ordre-system fra fil (objekt-deserialisering) *********/
        //public static FrisørSystem HentData()
        //{
        //    FileStream fileStream = null;

        //    try   // Check for om fil kan læses
        //    {
        //        // Åben fil for læsning
        //        fileStream = new FileStream(FILNAVN, FileMode.Open, FileAccess.Read);
        //    }
        //    catch (Exception)    // fejl ved åbning af fil
        //    {
        //        fileStream.Close();
        //        throw;   // kast exception videre til UI
        //    }

        //    // skab binary-formatter til objekt-serialisering
        //    BinaryFormatter binFormatter = new BinaryFormatter();

        //    // Deserialisér filestream til frisørsystem
        //    FrisørSystem frisørsystem = (FrisørSystem)binFormatter.Deserialize(fileStream);

        //    fileStream.Close();

        //    return frisørsystem;
        //}
#endregion

        #region ************ Persistens database *****************

        //public static FrisørSystem HentData()
        //{


        //    //try   // Check for om fil kan læses
        //    //{
        //        minDBFacade.IndlaesVarer();
        //    //}
        //    //catch (Exception)    // fejl ved åbning af fil
        //    //{
        //    //    throw;   // kast exception videre til UI
        //    //}
        //}

        // Metoden kaldes fra DB-facade, når varerne skal indlæses fra databasen
        // Bemærk at metoden er internal, så den kan ikke ses fra GUI
        internal void OpretVareModel(long varenr, string betegnelse, double pris, uint beholdning)
        {
               Vare vare = vareCol.TilfoejVare(varenr, betegnelse, pris);
                vare.ModtagVarer(beholdning);
        }
        #endregion

    }
}
